using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.ServiceModel;
using System.Threading;
using AutoMapper;
using Core;
using IglooCoder.Commons.WcfNhibernate;
using Infrastucture;
using WcfService1.DTO;
using Omu.ValueInjecter;

namespace WcfService1
{
    // NOTE: You can use the "Rename" command on the "Refactor" Spk to change the class name "SpkServices" in code, svc and config file together.
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    [NHibernateContext]
    public class SpkServices : ISpkServices
    {
        private readonly SpkRepository SpkRepository;
        private WcfSessionStorage _session;
        private DeliveryOrderRepository DORepository;
        private SalesInvoiceRepository SIRepository;
        public SpkServices()
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            _session = new  WcfSessionStorage();
            SpkRepository = new SpkRepository(_session);
            DORepository = new DeliveryOrderRepository(_session);
            SIRepository = new SalesInvoiceRepository(_session);

        }

        #region ISpkServices Members

        public List<SpkDTO> GetList(int page, out long recordCount, string sortProperty = null, string sortType = "ASC")
        {
            var Spks = new List<Spk>();
            var Results = new List<SpkDTO>();

            if (string.IsNullOrEmpty(sortProperty))
            {
                Spks = SpkRepository.GetDataPaged(page, 30, "SpkDate", "DESC").ToList();
            }
            else
            {
                Spks = SpkRepository.GetDataPaged(page, 30, sortProperty, sortType).ToList();
            }

            recordCount = SpkRepository.RecordCount;

            Spks.ForEach(x =>
                             {
                                 SpkDTO SpkDto = x.ConvertToDTO<Spk, SpkDTO>();
                                 SpkDto.Status = (Status) x.Status;
                                 Results.Add(SpkDto);
                             }
                );

            return Results;
        }

        public bool Save(SpkDTO SpkDTO)
        {
            bool res = false;
            try
            {
                SpkRepository.ExecuteTransactionNative(()=>
                                                           {
                                                               Spk Spk = SpkRepository.GetDataOne(x => x.NoSPK == SpkDTO.NoSPK);
                                                               if (Spk == null)
                                                               {
                                                                   Spk = new Spk();
                                                                   Mapper.Map(SpkDTO, Spk);
                                                                   //Untuk New entry dari transaksi bukan dari email
                                                                   if (String.IsNullOrEmpty(Spk.NoSPK))
                                                                       Spk.NoSPK = GetLastNoSPK();
                                                                   foreach (SpkDetail spkDetail in Spk.SpkDetails)
                                                                   {
                                                                       spkDetail.Spk = Spk;
                                                                       spkDetail.SpkDetailId = 0;
                                                                   }
                                                                   SpkRepository.SaveOrUpdate(Spk);
                                                               }
                                                               else
                                                               {
                                                                   //Jika Status Void dan Close tdk boleh Update
                                                                   if (Spk.Status == (int)Status.Void || Spk.Status == (int)Status.Close)
                                                                       throw new Exception("Tidak bisa di Update Status sudah Close atau Void!");

                                                                   SpkRepository.Delete(Spk);
                                                                   var spk = new Spk();
                                                                   spk.modified_date = DateTime.Now;
                                                                   spk.created_date = Spk.created_date;
                                                                   Mapper.Map(SpkDTO, spk);
                                                                   foreach (var spkDetail in spk.SpkDetails)
                                                                       spkDetail.Spk = spk;
                                                                   SpkRepository.Session.SaveOrUpdateCopy(spk);
                                                              
                                                               }

                                                               res = true;
                             
                                                           });

                          }
            catch (Exception)
            {
                res = false;
                throw;
            }

            return res;
        }


        public bool Delete(SpkDTO SpkDto)
        {
            bool res;
            try
            {
                var Spk = new Spk();
                Mapper.Map(SpkDto, Spk);
                SpkRepository.Delete(Spk);
                res = true;
            }
            catch (Exception)
            {
                res = false;
            }

            return res;
        }


        public List<SpkDTO> GetListByCriteria(Dictionary<String, Object> criteria, string expression, int page,
                                              out long recordCount)
        {
            var Spks = new List<Spk>();
            var Results = new List<SpkDTO>();
            Spks = SpkRepository.GetDataPaged(criteria, expression, page, 30).ToList();
            recordCount = SpkRepository.RecordCount;
            Spks.ForEach(x =>
                    {
                        SpkDTO SpkDto = x.ConvertToDTO<Spk, SpkDTO>();
                        SpkDto.Status = (Status)x.Status;
                        Results.Add(SpkDto);
                    }
                );

            return Results;
        }


        public List<SpkDTO> GetAllSpk()
        {
            IList<Spk> Spks = SpkRepository.GetDataList(x => x.Status == Convert.ToInt16(Status.Open));
            List<SpkDTO> Results = Spks.Select((x) => new SpkDTO {NoSPK = x.NoSPK}).ToList();
            return Results;
        }


        public SpkDTO GetSpk(String NoSPK)
        {
            Spk spk = SpkRepository.GetDataOne(x => x.NoSPK == NoSPK);
            var spkDto = new SpkDTO();
            spkDto.InjectFrom<CloneInjection>(spk);
            return spkDto;
        }

        public List<SpkDTO> GetSpkList(string kodeSpk)
        {
            List<Spk> Spks = SpkRepository.GetDataList(x => x.NoSPK.Contains(kodeSpk)).ToList();
            var Results = new List<SpkDTO>();
            Spks.ForEach(x =>
                             {
                                 var spkDto = new SpkDTO();
                                 spkDto.InjectFrom<CloneInjection>(x);
                                 Results.Add(spkDto);
                             }
                );

            return Results;
        }


        public bool DeleteDetail(SpkDetailDTO SpkDetailDTO)
        {
            bool res;
            try
            {
                var SpkDetail = SpkRepository.Session.Get<SpkDetail>(SpkDetailDTO.SpkDetailId);
                SpkRepository.DeleteDetail(SpkDetail, SpkDetail.SpkDetailId);
                res = true;
            }
            catch (Exception)
            {
                res = false;
            }

            return res;
        }

        public string GetLastNoSPK()
        {
            var appParamServices = new AppParamServices();
            AppParamDTO param = appParamServices.GetAppParamList("KodeSPK").FirstOrDefault();
            string res = SpkRepository.GetMaxNumber(param.AppParamValue);
            if (string.IsNullOrEmpty(res))
                res = param.AppParamValue;
            string formatSO = "0000";
            string kodeSO;
            string lastNo = string.Empty;
            if (res.Length <= 4)
            {
                lastNo = formatSO;
                kodeSO = res;
            }
            else
            {
                lastNo = res.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[2];
                kodeSO = res.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0];
            }

            string soNum = formatSO.Substring(0, formatSO.Length - (int.Parse(lastNo) + 1).ToString().Length) +
                           (int.Parse(lastNo) + 1);
            return kodeSO + "/" + DateTime.Now.Year + "/" + soNum;
        }

        public bool SendEmail(SpkDTO spkDto, String DestinationFolder)
        {
            var mailServices = new MailServices();
            Spk spk = SpkRepository.GetDataOne(x => x.NoSPK == spkDto.NoSPK);
            spkDto = Mapper.Map(spk, spkDto);
            return mailServices.SendEmail(spkDto,DestinationFolder);
        }

        #endregion
    }
}